#include "include/Server.h"
#include "include/route.h"
#include "include/config.h"
#include "include/database.h"
#include "include/redis.h"
#include "include/emailSender.h"
#include <iostream>
#include <sstream>
#include <QtCore/QCoreApplication>
#include "../model/User.h"
#include "../model/Ticket.h"
#include "../model/Order.h"
#include "../model/Notification.h"
#include "../model/TicketOperation.h"
#include "../model/Sale.h"
#include "../model/Travel.h"
#include "../model/Browse.h"
#include "../model/Ask.h"
#include "../model/Check.h"
#include "../model/StationsPoints.h"
#include "../model/Stations.h"
#include "../model/Game.h"
#include "../model/Train.h"
#include "../model/StationTrain.h"


#ifdef _WIN32
#include <windows.h>
#endif

void CreatDatabase() {
    // 初始化所有数据库表
    User().initDatabase();
    Ticket().initDatabase();
    Order().initDatabase();
    Notification().initDatabase();
    TicketOperation().initDatabase();
    Sale().initDatabase();
    Travel().initDatabase();
    Browse().initDatabase();
    Ask().initDatabase();
    StationsPoint().initDatabase();
    Station().initDatabase();
    Check().initDatabase();
    Game().initDatabase();
    Train().initDatabase();
    StationTrain().initDatabase();
}

#include <fstream>
#include <sstream>
#include <vector>
#include <map>
#include <string>
#include <iostream>

#include "JsonValue.h"    // 若需要，根据实际情况调整

///**
// * 从 UTF-8 编码文件中读取站点数据，清空 stations 表后批量插入
// * 文件格式：每行一个站点，字段用分隔符分隔（示例：地址|城市|站点名称|角色）
// * @param filePath 本地文件路径（如 "D:/data/stations.txt"）
// * @param delimiter 字段分隔符（默认用 '|'，可根据文件调整）
// * @return bool 执行结果（true=成功，false=失败）
// */
//bool readFileAndBatchInsertStations(const std::string& filePath, const char delimiter = '|') {
//    try {
//        // ===================== 第一步：读取 UTF-8 编码文件 =====================
//        std::ifstream file(filePath, std::ios::in);
//        if (!file.is_open()) {
//            std::cerr << "文件打开失败：" << filePath << std::endl;
//            return false;
//        }
//
//        std::vector<std::map<std::string, std::string>> stationList;  // 存储读取的站点数据
//        std::string line;
//
//        // 按行读取文件（文件需为 UTF-8 编码，避免中文乱码）
//        while (std::getline(file, line)) {
//            if (line.empty()) continue;
//
//            std::stringstream ss(line);
//            std::string address, city, name, role;  // 对应 stations 表的字段
//
//            // 按分隔符解析每行字段（需和文件格式严格对应）
//            std::getline(ss, name, delimiter);
//            std::getline(ss, address, delimiter);
//           std::getline(ss, city, delimiter);
//
//
//            // 过滤无效数据（根据实际需求调整）
//            if (city.empty() || name.empty()) {
//                std::cerr << "跳过无效数据行：" << line << std::endl;
//                continue;
//            }
//
//            // 封装成站点对象，添加到列表
//            std::map<std::string, std::string> station;
//            station["address"] = address;
//            station["city"] = city;
//            station["name"] = name;
//            station["role"] = "PlaneStation";
//            // 若表有 createdAt 等自增/默认字段，无需手动添加（数据库自动处理）
//            stationList.push_back(station);
//        }
//        file.close();  // 关闭文件
//
//        if (stationList.empty()) {
//            std::cerr << "文件中无有效站点数据：" << filePath << std::endl;
//            return false;
//        }
//        std::cout << "成功读取 " << stationList.size() << " 条站点数据" << std::endl;
//
//
//        // ===================== 第三步：批量插入数据（高效） =====================
//        // 构建批量插入 SQL（适配 stations 表字段，避免频繁执行 SQL）
//        std::string insertSql = "INSERT INTO stations (address, city, name, role) VALUES ";
//        for (size_t i = 0; i < stationList.size(); ++i) {
//            auto& station = stationList[i];
//
//
//            // 拼接单条数据（注意：UTF-8 字符串直接拼接，DB 连接需为 utf8mb4）
//            insertSql += "('" + Model::escapeSqlLiteral(station["address"]) + "', ";
//            insertSql += "'" + Model::escapeSqlLiteral(station["city"]) + "', ";
//            insertSql += "'" + Model::escapeSqlLiteral(station["name"]) + "', ";
//            insertSql += "'" + Model::escapeSqlLiteral(station["role"]) + "')";
//
//            // 非最后一条数据加逗号分隔
//            if (i != stationList.size() - 1) {
//                insertSql += ", ";
//            }
//        }
//
//        // 执行批量插入（复用 DBConnector 的 query 或 execute 方法）
//        DBConnector::getInstance()->execute(insertSql);  // 无返回结果用 execute，有结果用 query
//        std::cout << "批量插入成功！共插入 " << stationList.size() << " 条数据" << std::endl;
//
//        return true;
//    } catch (const std::exception& e) {
//        std::cerr << "执行失败：" << e.what() << std::endl;
//        return false;
//    }
//}

// ===================== 调用示例（和 getCities 一样，直接调用即可） =====================
// 在你的主函数或初始化逻辑中调用：
// readFileAndBatchInsertStations("D:/data/stations.txt");  // 传入你的文件路径

//void initDatabase() {
//    Ticket ticket1;
//    ticket1.name="G987k";
//    ticket1.from="广州";
//    ticket1.to="深圳";
//    ticket1.type=TypeOfTicket::HIGHSPEEDTRAINFirstClass;
//    ticket1.startTime="2025-11-20 10:00:00";
//    ticket1.endTime="2025-11-20 10:30:00";
//    ticket1.price="99.5";
//    ticket1.cnt=100;
//    ticket1.save();
//
//    Ticket ticket2;
//    ticket2.name="G987k";
//    ticket2.from="广州";
//    ticket2.to="深圳";
//    ticket2.type=TypeOfTicket::HIGHSPEEDTRAINSecondClass;
//    ticket2.startTime="2025-11-20 10:00:00";
//    ticket2.endTime="2025-11-20 10:30:00";
//    ticket2.price="74.5";
//    ticket2.cnt=100;
//    ticket2.save();
//
//    Ticket ticket3;
//    ticket3.name="D983k";
//    ticket3.from="广州";
//    ticket3.to="深圳";
//    ticket3.type=TypeOfTicket::QUICKSPEEDTRAINFirstClass;
//    ticket3.startTime="2025-11-20 10:00:00";
//    ticket3.endTime="2025-11-20 10:30:00";
//    ticket3.price="79.5";
//    ticket3.cnt=100;
//    ticket3.save();
//
//    Ticket ticket4;
//    ticket4.name="D983k";
//    ticket4.from="广州";
//    ticket4.to="深圳";
//    ticket4.type=TypeOfTicket::QUICKSPEEDTRAINSecondClass;
//    ticket4.startTime="2025-11-20 10:00:00";
//    ticket4.endTime="2025-11-20 10:30:00";
//    ticket4.price="59.5";
//    ticket4.cnt=100;
//    ticket4.save();
//
//    Ticket ticket5;
//    ticket5.name="K953k";
//    ticket5.from="广州";
//    ticket5.to="深圳";
//    ticket5.type=TypeOfTicket::NORMALLQUICKTRAINHardBed;
//    ticket5.startTime="2025-11-20 10:00:00";
//    ticket5.endTime="2025-11-20 10:30:00";
//    ticket5.price="49.5";
//    ticket5.cnt=100;
//    ticket5.save();
//}

int main(int argc, char* argv[]) {
    QCoreApplication qtApp(argc, argv);  // 满足 QtSql 对 QCoreApplication 的要求
    #ifdef _WIN32
        // 设置控制台输出编码为 UTF-8（Windows 特定）
        SetConsoleOutputCP(65001);
        // 同时设置输入编码（可选）
        SetConsoleCP(65001);
    #endif

    Config cfg;

    cfg.show();

    // 连接数据库
    DBConnector db(cfg.dbHost, cfg.dbUser, cfg.dbPassword, cfg.dbName, stoi(cfg.dbPort));

    if(!db.connect()) {
        std::cerr << "Failed to connect to database. Error: " << db.getError() << std::endl;
        return 1;
    }

    RdConnector rd(cfg.redisHost, cfg.redisPort, cfg.redisPassword,stoi(cfg.redisdb));

    if(!rd.connect()) {
        std::cerr << "Failed to connect to redis. Error: " << rd.getError() << std::endl;
        return 1;
    }
//
    EmailSender es(cfg.smtp_host, cfg.smtp_port, cfg.smtp_user, cfg.smtp_password, cfg.smtp_from);
//
    if (!es.init()){
        std::cerr << "Failed to connect to email server. Error: " << std::endl;
        return 1;
    }

    JWT jwt;

    CreatDatabase();

//    readFileAndBatchInsertStations("../airports.txt",' ');

//    initDatabase();

//    es.sendVerificationCode("chenh735@mail2.sysu.edu.cn", "122256");

    // 创建服务器
    Server app(stoi(cfg.serverPort));
    registerRoutes(app);

    // 启动服务器
    app.run();

    return 0;
}

